package cz.farin.mandelinka;


public class BugHandle {
	
	private Bug bug; //user given interface
	private int number;
	
	private boolean alive;
	
	private int x, y; //position
	private Direction rotation;
		
	private int score;
	
	private Movement requestedMove;
	
	private Surroundings surroundings;
	
	public BugHandle(Bug bug, int number) {
		this.bug = bug;
		this.number = number;
		alive = true;
		surroundings = new Surroundings();		
	}
	
	/*void placeBug(int x, int y, Direction rotation) {
		this.x = x;
		this.y = y;
		this.rotation = rotation;
	}*/

	public Direction getRotation() {
		return rotation;
	}

	public void setRotation(Direction rotation) {
		this.rotation = rotation;
	}
	
	public boolean isAlive() {
		return alive;
	}

	public void setAlive(boolean alive) {
		this.alive = alive;
	}

	public int getScore() {
		return score;
	}
	
	public void increaseScore(int increase) {
		score += increase;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}	

	public Bug getBug() {
		return bug;
	}

	public Surroundings getSurroundings() {
		return surroundings;
	}
	
	public BugInfo toBugInfo() {
		BugInfo bi = new BugInfo();
		bi.setNumber(number);
		bi.setRotation(rotation);
		return bi;
	}

	public Movement getRequestedMove() {
		return requestedMove;
	}	

	public Movement requestMove() {
		Movement requestedMove = null;
		try {
			requestedMove = bug.move(surroundings);
		} catch (Throwable t) {
			t.printStackTrace();
			setAlive(false);
			increaseScore(Simulation.SCORE_EXCEPTION_PENALTY);
		}
		if (requestedMove == null) {
			requestedMove = Movement.NO_MOVE;
		}
		this.requestedMove = requestedMove;
		return requestedMove;
	}	
	
	public Position getActualPosition() {
		return new Position(x,y);
	}
	
	public Position getRequestedPosition() {
		switch (requestedMove) {
		case MOVE_FORWARD:
			switch (rotation) {
			case N:
				return new Position(x,y-1);
			case E:
				return new Position(x+1,y);
			case S:
				return new Position(x,y+1);
			case W:
				return new Position(x-1,y);
			}
			throw new IllegalStateException(); //should never happen
		case MOVE_BACKWARD:	
			switch (rotation) {
			case N:
				return new Position(x,y+1);
			case E:
				return new Position(x-1,y);
			case S:
				return new Position(x,y-1);
			case W:
				return new Position(x+1,y);
			}
			throw new IllegalStateException(); //should never happen
		default:
			return new Position(x,y);
		}
	}
	
	public void doMove() {
		switch (requestedMove) {
		case TURN_LEFT:
			rotation = rotation.rotateLeft();
			break;
		case TURN_RIGHT:
			rotation = rotation.rotateRight();
			break;
		case MOVE_FORWARD:
		case MOVE_BACKWARD:	
			Position p = getRequestedPosition();
			x = p.x;
			y = p.y;
			break;
		}
	}
	
	public void changeIllegalMove() {
		if (requestedMove == Movement.MOVE_BACKWARD || requestedMove == Movement.MOVE_FORWARD) {
			requestedMove = Movement.NO_MOVE;
		}		
	}
	

}
